home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / glibc108.gz / glibc108 / glibc-1.08.1 / sysdeps / posix / sysd-stdio.c < prev    next >
C/C++ Source or Header  |  1994-06-03  |  5KB  |  190 lines

  1. /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <errno.h>
  21. #include <stddef.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <fcntl.h>
  28. #include <unistd.h>
  29.  
  30. /* Read N bytes into BUF from COOKIE.  */
  31. int
  32. DEFUN(__stdio_read, (cookie, buf, n),
  33.       PTR cookie AND register char *buf AND register size_t n)
  34. {
  35.   CONST int fd = (int) cookie;
  36. #if    defined (EINTR) && defined (EINTR_REPEAT)
  37.   int save = errno;
  38.   int nread;
  39.  
  40.  try:;
  41.   errno = 0;
  42.   nread = __read (fd, buf, (int) n);
  43.   if (nread < 0)
  44.     {
  45.       if (errno == EINTR)
  46.     goto try;
  47.       return -1;
  48.     }
  49.   errno = save;
  50.   return nread;
  51.  
  52. #else    /* No EINTR.  */
  53.   return __read (fd, buf, n);
  54. #endif
  55. }
  56.  
  57.  
  58. /* Write N bytes from BUF to COOKIE.  */
  59. int
  60. DEFUN(__stdio_write, (cookie, buf, n),
  61.       PTR cookie AND register CONST char *buf AND register size_t n)
  62. {
  63.   CONST int fd = (int) cookie;
  64.   register size_t written = 0;
  65.  
  66.   while (n > 0)
  67.     {
  68.       int count = __write (fd, buf, (int) n);
  69.       if (count > 0)
  70.     {
  71.       buf += count;
  72.       written += count;
  73.       n -= count;
  74.     }
  75.       else if (count < 0
  76. #if    defined (EINTR) && defined (EINTR_REPEAT)
  77.            && errno != EINTR
  78. #endif
  79.            )
  80.     /* Write error.  */
  81.     return -1;
  82.     }
  83.  
  84.   return (int) written;
  85. }
  86.  
  87.  
  88. /* Move COOKIE's file position *POS bytes, according to WHENCE.
  89.    The new file position is stored in *POS.
  90.    Returns zero if successful, nonzero if not.  */
  91. int
  92. DEFUN(__stdio_seek, (cookie, pos, whence),
  93.       PTR cookie AND fpos_t *pos AND int whence)
  94. {
  95.   off_t new;
  96.   new = __lseek ((int) cookie, (off_t) *pos, whence);
  97.   if (new < 0)
  98.     return 1;
  99.   *pos = (fpos_t) new;
  100.   return 0;
  101. }
  102.  
  103.  
  104. /* Close COOKIE.  */
  105. int
  106. DEFUN(__stdio_close, (cookie), PTR cookie)
  107. {
  108.   return __close ((int) cookie);
  109. }
  110.  
  111. /* Return the POSIX.1 file descriptor associated with COOKIE,
  112.    or -1 for errors.  If COOKIE does not relate to any POSIX.1 file
  113.    descriptor, this should return -1 with errno set to EOPNOTSUPP.  */
  114. int
  115. DEFUN(__stdio_fileno, (cookie), PTR cookie)
  116. {
  117.   return (int) cookie;
  118. }
  119.  
  120.  
  121. /* Open the given file with the mode given in the __io_mode argument.  */
  122. int
  123. DEFUN(__stdio_open, (filename, m, cookieptr),
  124.       CONST char *filename AND __io_mode m AND PTR *cookieptr)
  125. {
  126.   int fd;
  127.   int mode;
  128.  
  129.   if (m.__read && m.__write)
  130.     mode = O_RDWR;
  131.   else
  132.     mode = m.__read ? O_RDONLY : O_WRONLY;
  133.  
  134.   if (m.__append)
  135.     mode |= O_APPEND;
  136.   if (m.__exclusive)
  137.     mode |= O_EXCL;
  138.   if (m.__truncate)
  139.     mode |= O_TRUNC;
  140.  
  141.   if (m.__create)
  142.     fd = __open (filename, mode | O_CREAT,
  143.          S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
  144.   else
  145.     fd = __open (filename, mode);
  146.  
  147.   if (fd < 0)
  148.     return -1;
  149.  
  150.   *cookieptr = (PTR) fd;
  151.   return 0;
  152. }
  153.  
  154.  
  155. /* Open FILENAME with the mode in M.  Use the same magic cookie
  156.    already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN.  */
  157. int
  158. DEFUN(__stdio_reopen, (filename, m, cookieptr),
  159.       CONST char *filename AND __io_mode m AND
  160.       PTR *cookieptr AND __io_close_fn closefn)
  161. {
  162.   PTR newcookie;
  163.  
  164.   /* We leave the old descriptor open while we open the file.
  165.      That way ``freopen ("/dev/stdin", "r", stdin)'' works.  */
  166.  
  167.   if (__stdio_open (filename, m, &newcookie))
  168.     {
  169.       if (errno == ENFILE || errno == EMFILE)
  170.     {
  171.       /* We are out of file descriptors.  Try closing the old one and
  172.          retrying the open.  */
  173.       (void) (*closefn) (*cookieptr);
  174.       if (__stdio_open (filename, m, &newcookie))
  175.         return -1;
  176.     }
  177.     }
  178.  
  179.   if (newcookie != *cookieptr)
  180.     {
  181.       if (closefn != __stdio_close ||
  182.       /* Try to move the descriptor to the desired one.  */
  183.       __dup2 ((int) newcookie, (int) *cookieptr) < 0)
  184.     /* Didn't work.  Give the caller the new cookie.  */
  185.     *cookieptr = newcookie;
  186.     }
  187.  
  188.   return 0;
  189. }
  190.